﻿#include <QScriptEngine>
#include "mark_config_dialog.h"
#include "ui_mark_config_dialog.h"

MarkConfigDialog::MarkConfigDialog(QWidget* parent) :
	QDialog(parent),
	ui(new Ui::MarkConfigDialog)
	, current_menu_atrr_checkbox_(NULL)
{
	ui->setupUi(this);

	InitAttrConfigGroupBox();//初始化属性配置
	attr_manage_state_ = ATTRMANAGE_INIT;//记录当前为初始状态

	//属性管理菜单
	attr_manage_menu_ = new QMenu;
	action_attr_see_ = new QAction(QStringLiteral("查看"));
	action_attr_edit_ = new QAction(QStringLiteral("编辑"));
	action_attr_delete_ = new QAction(QStringLiteral("删除"));
	attr_manage_menu_->addAction(action_attr_see_);
	attr_manage_menu_->addAction(action_attr_edit_);
	attr_manage_menu_->addAction(action_attr_delete_);
	connect(action_attr_see_, &QAction::triggered, this, &MarkConfigDialog::AttrSeeAction);//查看
	connect(action_attr_edit_, &QAction::triggered, this, &MarkConfigDialog::AttrEditAction);//编辑
	connect(action_attr_delete_, &QAction::triggered, this, &MarkConfigDialog::AttrDeleteAction);//删除

	connect(ui->pushButton_check_script_, &QPushButton::clicked, this, &MarkConfigDialog::AttrScriptCheck);//检查脚本内容
	connect(ui->pushButton_new_, &QPushButton::clicked, this, &MarkConfigDialog::NewAttr);//新增属性
	connect(ui->pushButton_edit_, &QPushButton::clicked, this, &MarkConfigDialog::AttrEditPushbutton);//属性编辑
	connect(ui->pushButton_edit_ok_, &QPushButton::clicked, this, &MarkConfigDialog::AttrEditOkPushbutton);//属性编辑
	connect(ui->pushButton_add_attr_, &QPushButton::clicked, this, &MarkConfigDialog::AddAttr);//新增属性完成
	connect(ui->pushButton_ok_, &QPushButton::clicked, this, &MarkConfigDialog::SettingFinished);//属性设置完成
	connect(ui->textEdit_attr_script_, &QTextEdit::textChanged, this, &MarkConfigDialog::ScriptTextChanged);//属性脚本文本变化
	connect(ui->lineEdit_attr_name_, &QLineEdit::textChanged, this, &MarkConfigDialog::AttrNameTextChanged);//属性名称文本变化

	SetAttrGroupBoxVisible(false);//隐藏属性配置框
}

MarkConfigDialog::~MarkConfigDialog()
{
	delete ui;
}

void MarkConfigDialog::SetAlreadyAttr(const QList<QPair<QString, QString>>& attr_script_list)
{
	//添加属性到界面
	foreach(const auto & attr_script, attr_script_list)
	{
		QString name = attr_script.first;
		QString script = attr_script.second;
		//界面添加复选款
		QCheckBox* box = new QCheckBox(name);
		box->setContextMenuPolicy(Qt::CustomContextMenu);
		connect(box, &QCheckBox::customContextMenuRequested, this, &MarkConfigDialog::AttrCheckBoxCustomContextMenu);//右键菜单
		ui->hLayout_mark_attr_->addWidget(box);
		//存储属性脚本信息信息
		attr_script_map_.insert(name, script);
	}
}

void MarkConfigDialog::SetAlreadyRegulation(const QString& markname_regulation, const QStringList& enable_attr_list)
{
	//标签名称规则
	if (markname_regulation == QStringLiteral("标签%p%"))//默认
	{
		ui->radioButton_default_mark_name_->setChecked(true);
		ui->radioButton_custom_mark_name_->setChecked(false);
	}
	else//自定义
	{
		ui->radioButton_default_mark_name_->setChecked(false);
		ui->radioButton_custom_mark_name_->setChecked(true);
		ui->lineEdit_mark_name_->setText(markname_regulation);
	}
	//启用的属性
	for (int i = 0; i < ui->hLayout_mark_attr_->count(); ++i)
	{
		QLayoutItem* child = ui->hLayout_mark_attr_->itemAt(i);
		QCheckBox* box = qobject_cast<QCheckBox*>(child->widget());
		if (enable_attr_list.contains(box->text()))
		{
			box->setChecked(true);
		}
	}
}

void MarkConfigDialog::InitAttrConfigGroupBox()
{
	disconnect(ui->textEdit_attr_script_, &QTextEdit::textChanged, this, &MarkConfigDialog::ScriptTextChanged);//屏蔽属性脚本文本变化信号槽
	disconnect(ui->lineEdit_attr_name_, &QLineEdit::textChanged, this, &MarkConfigDialog::AttrNameTextChanged);//屏蔽属性名称文本变化信号槽
	ui->lineEdit_attr_name_->clear();//清空属性名称输入框
	ui->textEdit_attr_script_->clear();//清空脚本输入框
	ui->lineEdit_attr_name_->setEnabled(true);//属性名称输入框可用
	ui->textEdit_attr_script_->setEnabled(true);//脚本输入框可用
	ui->label_attr_name_->setVisible(false);//隐藏名称重复提示标签
	ui->label_check_script_result_->setText(QStringLiteral("检测结果：____"));//初始化脚本检测结果标签
	ui->pushButton_add_attr_->setVisible(false);//隐藏属性添加按钮
	ui->pushButton_edit_->setVisible(false);//隐藏属性编辑按钮
	ui->pushButton_edit_ok_->setVisible(false);//隐藏属性编辑完成按钮
	connect(ui->textEdit_attr_script_, &QTextEdit::textChanged, this, &MarkConfigDialog::ScriptTextChanged);//属性脚本文本变化
	connect(ui->lineEdit_attr_name_, &QLineEdit::textChanged, this, &MarkConfigDialog::AttrNameTextChanged);//属性名称文本变化
}

void MarkConfigDialog::SetAttrGroupBoxVisible(bool visible)
{
	if (ui->groupBox_attr_setting_->isVisible() == visible) return;
	disconnect(ui->textEdit_attr_script_, &QTextEdit::textChanged, this, &MarkConfigDialog::ScriptTextChanged);//屏蔽属性脚本文本变化信号槽
	disconnect(ui->lineEdit_attr_name_, &QLineEdit::textChanged, this, &MarkConfigDialog::AttrNameTextChanged);//屏蔽属性名称文本变化信号槽
	ui->groupBox_attr_setting_->setVisible(visible);//显隐属性配置框
	connect(ui->textEdit_attr_script_, &QTextEdit::textChanged, this, &MarkConfigDialog::ScriptTextChanged);//属性脚本文本变化
	connect(ui->lineEdit_attr_name_, &QLineEdit::textChanged, this, &MarkConfigDialog::AttrNameTextChanged);//属性名称文本变化
}

void MarkConfigDialog::AttrScriptCheck()
{
	QScriptEngine engine;
	QPointF cpoint(0, 0);//脚本检测，检测时使用
	engine.globalObject().setProperty("PX", cpoint.x());
	engine.globalObject().setProperty("PY", cpoint.y());
	engine.globalObject().setProperty("px", cpoint.x());
	engine.globalObject().setProperty("py", cpoint.y());
	QString script = ui->textEdit_attr_script_->toPlainText();
	QScriptValue v = engine.evaluate(script);
	if (v.isError())
	{
		ui->label_check_script_result_->setText(QStringLiteral("检测结果：错误"));
	}
	else
	{
		ui->label_check_script_result_->setText(QStringLiteral("检测结果：正确"));
		//判断当前状态，确认显示按钮
		if (attr_manage_state_ == ATTRMANAGE_ADDING || attr_manage_state_ == ATTRMANAGE_ADD)
		{
			ui->pushButton_add_attr_->setVisible(true);
		}
		else if (attr_manage_state_ == ATTRMANAGE_EDITTING || attr_manage_state_ == ATTRMANAGE_EDIT)
		{
			ui->pushButton_edit_ok_->setVisible(true);
		}
	}
}

void MarkConfigDialog::NewAttr()
{
	//判断当前模式，已在初始、编辑、新建，必要信息在界面提示
	if (attr_manage_state_ == ATTRMANAGE_INIT)
	{
		InitAttrConfigGroupBox();//初始化属性相关控件
	}
	else if (attr_manage_state_ == ATTRMANAGE_ADDING)
	{
		int ret = QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("上次新建属性还未保存，是否继续？"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
		if (ret == QMessageBox::No)
		{
			return;
		}
		else
		{
			InitAttrConfigGroupBox();//初始化属性相关控件
		}
	}
	else if (attr_manage_state_ == ATTRMANAGE_EDITTING)
	{
		int ret = QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("正在编辑的属性还未保存，是否继续？"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
		if (ret == QMessageBox::No)
		{
			return;
		}
		else
		{
			InitAttrConfigGroupBox();//初始化属性相关控件
		}
	}
	SetAttrGroupBoxVisible(true);//显示属性配置框
	attr_manage_state_ = ATTRMANAGE_ADD;//记录当前为新建状态
}

void MarkConfigDialog::AddAttr()
{
	//检测属性名称是否合格、是否存在
	QString attr_name = ui->lineEdit_attr_name_->text();
	//判断名称为空
	if (attr_name.isEmpty())
	{
		ui->label_attr_name_->setText(QStringLiteral("属性名不可为空"));
		ui->label_attr_name_->setVisible(true);
		return;
	}
	//判断重名
	if (attr_script_map_.contains(attr_name))
	{
		ui->label_attr_name_->setText(QStringLiteral("属性名已存在，请修改"));
		ui->label_attr_name_->setVisible(true);
		return;
	}
	//名称和配置写入本地配置
	QString attr_sript = ui->textEdit_attr_script_->toPlainText();
	emit AddAttrScriptSignal(attr_name, attr_sript);
	//界面添加新属性checkbox
	QCheckBox* box = new QCheckBox(attr_name);
	box->setContextMenuPolicy(Qt::CustomContextMenu);
	connect(box, &QCheckBox::customContextMenuRequested, this, &MarkConfigDialog::AttrCheckBoxCustomContextMenu);//右键菜单
	ui->hLayout_mark_attr_->addWidget(box);
	//attr_script_map_中添加新增的键值对
	attr_script_map_.insert(attr_name, ui->textEdit_attr_script_->toPlainText());
	//清空属性配置框
	InitAttrConfigGroupBox();
	//记录当前为新建状态
	attr_manage_state_ = ATTRMANAGE_INIT;
}

void MarkConfigDialog::SettingFinished()
{
	QString markname_regulation;
	if (ui->radioButton_default_mark_name_->isChecked())//使用默认标点名称规则
	{
		markname_regulation = QStringLiteral("标签%p%");
	}
	else if (ui->radioButton_custom_mark_name_->isChecked())//使用自定义标点名称规则
	{
		markname_regulation = ui->lineEdit_mark_name_->text();
	}
	//规则如果为空，使用默认规则
	markname_regulation = markname_regulation.isEmpty() ? QStringLiteral("标签%p%") : markname_regulation;
	//获取启用的属性
	QStringList attr_enable_list;
	for (int i = 0; i < ui->hLayout_mark_attr_->count(); ++i)
	{
		QLayoutItem* child = ui->hLayout_mark_attr_->itemAt(i);
		QCheckBox* box = qobject_cast<QCheckBox*>(child->widget());
		if (box->isChecked())
		{
			attr_enable_list.append(box->text());
		}
	}
	//保存到本地配置
	emit SaveMarkRegulationSignal(markname_regulation, attr_enable_list);
	close();
}

void MarkConfigDialog::ScriptTextChanged()
{
	//脚本变化，需要重新检测
	if (ui->pushButton_add_attr_->isVisible())
	{
		ui->pushButton_add_attr_->setVisible(false);
		ui->label_check_script_result_->setText(QStringLiteral("检测结果：____"));
	}
	//脚本变化，需要重新检测
	if (ui->pushButton_edit_ok_->isVisible())
	{
		ui->pushButton_edit_ok_->setVisible(false);
		ui->label_check_script_result_->setText(QStringLiteral("检测结果：____"));
	}
	//记录当前状态
	if (attr_manage_state_ == ATTRMANAGE_INIT || attr_manage_state_ == ATTRMANAGE_ADD)//初始化、新建
	{
		attr_manage_state_ = ATTRMANAGE_ADDING;//新建中
	}
	if (attr_manage_state_ == ATTRMANAGE_EDIT)//编辑
	{
		attr_manage_state_ = ATTRMANAGE_EDITTING;//编辑中
	}
}

void MarkConfigDialog::AttrNameTextChanged()
{
	if (ui->label_attr_name_->isVisible())
	{
		ui->label_attr_name_->setVisible(false);//隐藏名称重复提示标签
	}
	//记录当前状态
	if (attr_manage_state_ == ATTRMANAGE_INIT || attr_manage_state_ == ATTRMANAGE_ADD)//初始化、新建
	{
		attr_manage_state_ = ATTRMANAGE_ADDING;//新建中
	}
	if (attr_manage_state_ == ATTRMANAGE_EDIT)//编辑
	{
		attr_manage_state_ = ATTRMANAGE_EDITTING;//编辑中
	}
}

void MarkConfigDialog::AttrCheckBoxCustomContextMenu(const QPoint& pos)
{
	current_menu_atrr_checkbox_ = qobject_cast<QCheckBox*>(sender());
	attr_manage_menu_->exec(QCursor::pos());
}

void MarkConfigDialog::AttrSeeAction()
{
	Q_ASSERT(current_menu_atrr_checkbox_ != NULL);//断言属性名称不为空
	QString text = current_menu_atrr_checkbox_->text();
	Q_ASSERT(attr_script_map_.contains(text));//断言存在属性信息
	SetAttrGroupBoxVisible(true);//显示属性配置框
	ui->lineEdit_attr_name_->setText(text);
	ui->textEdit_attr_script_->setPlainText(attr_script_map_.value(text));
	//查看状态下，隐藏脚本监测等内容、不可编辑、编辑按钮显示
	ui->widget_script_tip_->setVisible(false);
	ui->lineEdit_attr_name_->setEnabled(false);
	ui->textEdit_attr_script_->setEnabled(false);
	ui->pushButton_edit_->setVisible(true);
	//记录状态为查看
	attr_manage_state_ = ATTRMANAGE_SEE;
}

void MarkConfigDialog::AttrEditAction()
{
	Q_ASSERT(current_menu_atrr_checkbox_ != NULL);//断言属性名称不为空
	QString text = current_menu_atrr_checkbox_->text();
	Q_ASSERT(attr_script_map_.contains(text));//断言存在属性信息
	SetAttrGroupBoxVisible(true);//显示属性配置框
	ui->lineEdit_attr_name_->setText(text);
	ui->textEdit_attr_script_->setPlainText(attr_script_map_.value(text));
	//查看状态下，隐藏脚本监测等内容、不可编辑、编辑按钮显示
	ui->widget_script_tip_->setVisible(true);
	ui->lineEdit_attr_name_->setEnabled(false);
	ui->textEdit_attr_script_->setEnabled(true);
	//记录状态为编辑
	attr_manage_state_ = ATTRMANAGE_EDIT;
}

void MarkConfigDialog::AttrEditPushbutton()
{
	Q_ASSERT(current_menu_atrr_checkbox_ != NULL);//断言属性名称不为空
	QString text = current_menu_atrr_checkbox_->text();
	Q_ASSERT(attr_script_map_.contains(text));//断言存在属性信息
	SetAttrGroupBoxVisible(true);//显示属性配置框
	ui->lineEdit_attr_name_->setText(text);
	ui->textEdit_attr_script_->setPlainText(attr_script_map_.value(text));
	//查看状态下，隐藏脚本监测等内容、不可编辑、编辑按钮显示
	ui->widget_script_tip_->setVisible(true);
	ui->lineEdit_attr_name_->setEnabled(false);
	ui->textEdit_attr_script_->setEnabled(true);
	ui->pushButton_edit_->setVisible(false);
	//记录状态为编辑
	attr_manage_state_ = ATTRMANAGE_EDIT;
}

void MarkConfigDialog::AttrEditOkPushbutton()
{
	//检测属性名称是否合格、是否存在
	QString attr_name = ui->lineEdit_attr_name_->text();
	//判断名称为空
	if (attr_name.isEmpty())
	{
		ui->label_attr_name_->setText(QStringLiteral("属性名不可为空"));
		ui->label_attr_name_->setVisible(true);
		return;
	}
	//名称和配置写入本地配置
	QString attr_sript = ui->textEdit_attr_script_->toPlainText();
	emit ReviseAttrScriptSignal(attr_name, attr_sript);
	//attr_script_map_中添加新增的键值对
	attr_script_map_.remove(attr_name);//移除旧的属性脚本映射关系
	attr_script_map_.insert(attr_name, attr_sript);
	//清空属性配置框
	InitAttrConfigGroupBox();
	//记录当前为新建状态
	attr_manage_state_ = ATTRMANAGE_INIT;
}

void MarkConfigDialog::AttrDeleteAction()
{
	Q_ASSERT(current_menu_atrr_checkbox_ != NULL);//断言属性控件不为空
	QString text = current_menu_atrr_checkbox_->text();
	Q_ASSERT(attr_script_map_.contains(text));//断言存在属性信息
	//判断删除的属性，是否正在属性框中操作
	if (!text.isEmpty())
	{
		//删除的属性框正在属性框中操作
		InitAttrConfigGroupBox();//初始化属性框
		attr_manage_state_ = ATTRMANAGE_INIT;//记录状态为初始化
	}
	//删除属性本地配置
	emit DeleteAttrScriptSignal(text);
	//删除映射关系
	attr_script_map_.remove(text);
	//删除界面checkbox
	for (int i = 0; i < ui->hLayout_mark_attr_->count(); ++i)
	{
		QLayoutItem* child = ui->hLayout_mark_attr_->itemAt(i);
		QCheckBox* box = qobject_cast<QCheckBox*>(child->widget());
		if (box != current_menu_atrr_checkbox_) continue;
		ui->hLayout_mark_attr_->takeAt(i);
		delete box;
		delete child;
		break;
	}
	//清空当前菜单操作属性文本记录
	current_menu_atrr_checkbox_ = NULL;
}
